/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file    adc.c
  * @brief   This file provides code for the configuration
  *          of the ADC instances.
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2025 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "adc.h"

/* USER CODE BEGIN 0 */

#define ADC_CHANNEL_COUNT  5
uint16_t g_AdcDmaCacheBuffer[ADC_CHANNEL_COUNT] = {0};
AdcValue_t adcAnalyseBuffer[ADC_CHANNEL_COUNT] = {0};
void adcAverageFilter(void);
/* USER CODE END 0 */

ADC_HandleTypeDef hadc1;

/* ADC1 init function */
void MX_ADC1_Init(void)
{

  /* USER CODE BEGIN ADC1_Init 0 */

  /* USER CODE END ADC1_Init 0 */

  ADC_ChannelConfTypeDef sConfig = {0};

  /* USER CODE BEGIN ADC1_Init 1 */
  //HAL_ADCEx_Calibration_Start(&hadc1);
  /* USER CODE END ADC1_Init 1 */

  /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.LowPowerAutoPowerOff = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 5;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T1_TRGO2;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.SamplingTimeCommon1 = ADC_SAMPLETIME_1CYCLE_5;
  hadc1.Init.SamplingTimeCommon2 = ADC_SAMPLETIME_1CYCLE_5;
  hadc1.Init.OversamplingMode = DISABLE;
  hadc1.Init.TriggerFrequencyMode = ADC_TRIGGER_FREQ_HIGH;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLINGTIME_COMMON_1;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_5;
  sConfig.Rank = ADC_REGULAR_RANK_4;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_9;
  sConfig.Rank = ADC_REGULAR_RANK_5;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN ADC1_Init 2 */
  ADC_Enable(&hadc1);
  HAL_ADC_Start(&hadc1);
  ADC1->CFGR1 |= 0x03;/*使能ADC触发DMA,连续模式*/
  /* USER CODE END ADC1_Init 2 */

}

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHandle)
{

  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspInit 0 */

  /* USER CODE END ADC1_MspInit 0 */
    /* ADC1 clock enable */
    __HAL_RCC_ADC_CLK_ENABLE();

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    /**ADC1 GPIO Configuration
    PA0     ------> ADC1_IN0
    PA3     ------> ADC1_IN3
    PA4     ------> ADC1_IN4
    PA5     ------> ADC1_IN5
    PB1     ------> ADC1_IN9
    */
    GPIO_InitStruct.Pin = A_Pin|VBUS_Pin|IBUS_Pin|POT_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    GPIO_InitStruct.Pin = NTC_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    HAL_GPIO_Init(NTC_GPIO_Port, &GPIO_InitStruct);

  /* USER CODE BEGIN ADC1_MspInit 1 */
  
  /* USER CODE END ADC1_MspInit 1 */
  }
}

void HAL_ADC_MspDeInit(ADC_HandleTypeDef* adcHandle)
{

  if(adcHandle->Instance==ADC1)
  {
  /* USER CODE BEGIN ADC1_MspDeInit 0 */

  /* USER CODE END ADC1_MspDeInit 0 */
    /* Peripheral clock disable */
    __HAL_RCC_ADC_CLK_DISABLE();

    /**ADC1 GPIO Configuration
    PA0     ------> ADC1_IN0
    PA3     ------> ADC1_IN3
    PA4     ------> ADC1_IN4
    PA5     ------> ADC1_IN5
    PB1     ------> ADC1_IN9
    */
    HAL_GPIO_DeInit(GPIOA, A_Pin|VBUS_Pin|IBUS_Pin|POT_Pin);

    HAL_GPIO_DeInit(NTC_GPIO_Port, NTC_Pin);

  /* USER CODE BEGIN ADC1_MspDeInit 1 */

  /* USER CODE END ADC1_MspDeInit 1 */
  }
}

/* USER CODE BEGIN 1 */

void adcDMAFinishCallBack(void)
{
  /*更新瞬时�?*/
  for( uint8_t i = 0; i<ADC_CHANNEL_COUNT; i++ )
  {
    adcAnalyseBuffer[i].valueInstance = g_AdcDmaCacheBuffer[i];
  }
  adcAverageFilter();//更新平均�?
}

void adcAverageFilter(void)//平均值滤�?
{
  //滤波vbus
  adcAnalyseBuffer[AN_DEF_VBUS].valueSum += adcAnalyseBuffer[AN_DEF_VBUS].valueInstance;
  adcAnalyseBuffer[AN_DEF_VBUS].valueCnt++;

  if( adcAnalyseBuffer[AN_DEF_VBUS].valueCnt>=128 ){
    adcAnalyseBuffer[AN_DEF_VBUS].valueAverage = adcAnalyseBuffer[AN_DEF_VBUS].valueSum>>7;//移位代替除法
    adcAnalyseBuffer[AN_DEF_VBUS].valueSum = 0;
    adcAnalyseBuffer[AN_DEF_VBUS].valueCnt = 0;
  }

  //滤波IBUS
  adcAnalyseBuffer[AN_DEF_IBUS].valueSum += adcAnalyseBuffer[AN_DEF_IBUS].valueInstance;
  adcAnalyseBuffer[AN_DEF_IBUS].valueCnt++;

  if( adcAnalyseBuffer[AN_DEF_IBUS].valueCnt>=128 ){
    adcAnalyseBuffer[AN_DEF_IBUS].valueAverage = adcAnalyseBuffer[AN_DEF_IBUS].valueSum>>7;//移位代替除法
    adcAnalyseBuffer[AN_DEF_IBUS].valueSum = 0;
    adcAnalyseBuffer[AN_DEF_IBUS].valueCnt = 0;
  }  

  //滤波POT
  adcAnalyseBuffer[AN_DEF_POT].valueSum += adcAnalyseBuffer[AN_DEF_POT].valueInstance;
  adcAnalyseBuffer[AN_DEF_POT].valueCnt++;

  if( adcAnalyseBuffer[AN_DEF_POT].valueCnt>=128 ){
    adcAnalyseBuffer[AN_DEF_POT].valueAverage = adcAnalyseBuffer[AN_DEF_POT].valueSum>>7;//移位代替除法
    adcAnalyseBuffer[AN_DEF_POT].valueSum = 0;
    adcAnalyseBuffer[AN_DEF_POT].valueCnt = 0;
  }  
  //滤波NTC
  adcAnalyseBuffer[AN_DEF_NTC].valueSum += adcAnalyseBuffer[AN_DEF_NTC].valueInstance;
  adcAnalyseBuffer[AN_DEF_NTC].valueCnt++;

  if( adcAnalyseBuffer[AN_DEF_NTC].valueCnt>=64 ){
    adcAnalyseBuffer[AN_DEF_NTC].valueAverage = adcAnalyseBuffer[AN_DEF_NTC].valueSum>>6;//移位代替除法
    adcAnalyseBuffer[AN_DEF_NTC].valueSum = 0;
    adcAnalyseBuffer[AN_DEF_NTC].valueCnt = 0;
  }

}

uint16_t u16AdcGetAverageValue(uint8_t u8Index)
{
  uint16_t retval = 0;
  if(u8Index<ADC_CHANNEL_COUNT){
    retval = adcAnalyseBuffer[u8Index].valueAverage;
  }
  return retval;
}


/* USER CODE END 1 */
